Site Characteristics

Copepods were collected by surface tow from sites across the Western Atlantic at several times throughout the year. The sites are shown below. Temperatures at the time of collection were measured using a manual thermometer.

coords = site_data %>%
  select(site, long, lat) %>%
  distinct()

site_map = map_data("world") %>% 
  filter(region %in% c("USA", "Canada")) %>% 
  ggplot() + 
  geom_polygon(aes(x = long, y = lat, group = group),
               fill = "lightgrey") + 
  coord_map(xlim = c(-85,-60),
            ylim = c(25, 48)) + 
  geom_point(data = coords,
             mapping = aes(x = long, y = lat, colour = site),
             size = 3) +
  scale_colour_manual(values = site_cols) + 
  labs(x = "Longitude", 
       y = "Latitude") + 
  theme_matt(base_size = 16)

site_temp_plot = full_data %>% 
  select(site, season, doy, collection_temp, collection_salinity) %>%  
  distinct() %>% 
  filter(doy > 100) %>% 
  ggplot(aes(x = doy, y = collection_temp, colour = site)) + 
  geom_line(linewidth = 1) + 
  geom_point(size = 6) +
  scale_colour_manual(values = site_cols) + 
  labs(y = "Temperature (°C)",
       x = "Day of the Year") +
  theme_matt() + 
  theme(legend.position = "right")

ggarrange(site_map, site_temp_plot, common.legend = T, legend = "bottom")

Exact locations for the sites are provided here.

site_data %>%  
  arrange(lat) %>%  
  select("Site" = site, "Region" = region, "Lat" = lat, "Long" = long) %>% 
  knitr::kable(align = "c")
Site Region Lat Long
Key Largo Florida 25.28391 -80.33014
Manatee River Florida 27.50561 -82.57277
Ft. Hamer Florida 27.52488 -82.43101
Tyler Cove Maryland 38.35083 -76.22902
Ganey’s Wharf Maryland 38.80555 -75.90906
Esker Point Connecticut 41.32081 -72.00166
Sawyer Park Maine 43.90698 -69.87179
St. Thomas de Kent Wharf New Brunswick 46.44761 -64.63692
Ritchie Wharf New Brunswick 47.00481 -65.56291

Nested within each of the three regions (South, Central, and Northern regions) are pairs of low and high salinity sites:

data.frame("Region" = c("South", "Central", "North"),
           "Low Salinity" = c("Ft. Hamer", "Ganey's Wharf", "Ritchie Wharf"),
           "High Salinity" = c("Manatee River", "Tyler Cove", "St. Thomas de Kent Wharf")) %>% 
  knitr::kable(align = "c")
Region Low.Salinity High.Salinity
South Ft. Hamer Manatee River
Central Ganey’s Wharf Tyler Cove
North Ritchie Wharf St. Thomas de Kent Wharf

 

There are fairly well-established divergences between high salinity and low salinity populations of Acartia tonsa. These sets of geographically proximate but isolated populations provide independent comparisons of the effects of seasonality.

season_cols = c("early" = "grey75", 
                "peak" = "grey50", 
                "late" = "grey25")

sal_regions = data.frame(region = rep(c("South", "Central", "North"), each = 2), 
                         site = c("Ft. Hamer", "Manatee River", 
                                  "Ganey's Wharf", "Tyler Cove", 
                                  "Ritchie Wharf", "St. Thomas de Kent Wharf"),
                         salinity = c("low", "high"))

sal_comps = full_data %>% 
  filter(site %in% sal_regions$site) %>% 
  inner_join(sal_regions, by = c("site")) %>% 
  select( region = region.y, site, salinity, season, doy, collection_temp, collection_salinity,
          size, ctmax, warming_tol) %>% 
  mutate(salinity = fct_relevel(salinity, "low", "high"),
         region = fct_relevel(region, "South", "Central", "North"))

sal_comp_temps = sal_comps %>%  
  select(salinity, season, region, collection_temp, collection_salinity) %>% 
  distinct() %>% 
  ggplot(aes(x = salinity, y = collection_temp, colour = season, group = season)) + 
  facet_wrap(region~.) + 
  geom_point(size = 4) + 
  geom_line(linewidth = 1.5) + 
  scale_colour_manual(values = season_cols) + 
  labs(y = "Collection Temp. (°C)",
       x = "") + 
  theme_matt_facets(base_size = 14)

sal_comp_sal = sal_comps %>%  
  select(salinity, season, region, collection_temp, collection_salinity) %>% 
  distinct() %>% 
  ggplot(aes(x = salinity, y = collection_salinity, colour = season, group = season)) + 
  facet_wrap(region~.) + 
  geom_point(size = 4) + 
  geom_line(linewidth = 1.5) + 
  scale_colour_manual(values = season_cols) + 
  labs(y = "Collection Salinity (psu)",
       x = "Salinity") + 
  theme_matt_facets(base_size = 14)

ggarrange(sal_comp_temps, sal_comp_sal, nrow = 2, common.legend = T, legend = "right")


# sal_comps %>%  
#   select(site, salinity, season, region, collection_temp, collection_salinity) %>% 
#   distinct() %>% 
#   ggplot(aes(x = collection_salinity, y = collection_temp, colour = site)) + 
#   facet_grid(region~.) + 
#   geom_point(size = 4) + 
#   #stat_ellipse() +
#   #geom_path(arrow = arrow(length = unit(0.1, "inches"), type = "closed")) + 
#   scale_colour_manual(values = site_cols) + 
#   theme_matt_facets(base_size = 14)

Critical Thermal Limits

A total of 356 individuals were examined. Critical thermal limits and body size measurements were made before individuals were preserved in ethanol. We excluded data for 6 individuals, detailed below. These individuals had either very low CTmax or were, upon re-examination of photographs, identified as juveniles instead of mature females.

excluded %>% 
  select(region, site, season, collection_temp, collection_salinity, replicate, tube, ctmax, size) %>% 
  knitr::kable(align = "c")
region site season collection_temp collection_salinity replicate tube ctmax size
Florida Manatee River peak 34.0 29 2 6 38.45833 0.616
Florida Manatee River peak 34.0 29 2 7 38.23750 0.593
Maryland Tyler Cove peak 29.5 15 2 2 36.84375 0.614
Connecticut Esker Point early 22.5 30 2 3 30.02604 0.687
Maine Sawyer Park peak 22.0 30 1 4 30.81424 0.865
New Brunswick St. Thomas de Kent Wharf late 13.5 28 1 3 28.78299 1.039

Critical thermal maxima (CTmax) was measured using a custom setup. The method uses a standard dynamic ramping assay to determine the maximum temperature individuals could sustain normal functioning. This differs from lethal temperatures, and indeed, all individuals observed so far recovered following the assay.

Individuals were rested for one hour after collection before the assay. During the assay, copepods were held in 0.2 um filtered seawater, adjusted to match the salinity at the time of collection with bottled spring water. During the assay, several ‘control’ individuals were maintained in this adjusted salinity solution, but did not experience the temperature ramp, to ensure that there was no background mortality.

Shown below are the measured CTmax values. Note: CTmax values for the early season Key Largo copepods were collected at the end of February 2023 as part of a separate project. Body size values were not measured during this project, nor were copepods individually preserved after the experiments. These early season CTmax values are included as a point of comparison. Individual measurements are shown in small points for each collection. The large point indicates the median value.

mean_ctmax = full_data %>% 
  group_by(site, season) %>% 
  summarize(mean_ctmax = mean(ctmax),
            median_ctmax = median(ctmax))

ggplot(full_data, aes(x = season, y = ctmax, colour = site)) + 
  geom_line(data = mean_ctmax, 
            aes(y = median_ctmax, group = site),
            position = position_dodge(width = 0.4),
            linewidth = 1) + 
  geom_point(position = position_jitterdodge(jitter.width = 0.1, jitter.height = 0,
                                             dodge.width = 0.4),
             alpha = 0.3) + 
  geom_point(data = mean_ctmax, 
             aes(y = median_ctmax),
             position = position_dodge(width = 0.4),
             size = 4) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax (°C)",
       x = "Season") +
  theme_matt() + 
  theme(legend.position = "right", 
        legend.title.align = 0.125)

Warming tolerance

Warming tolerance was calculated as the difference between measured CTmax values and the collection temperature. Lower warming tolerance values indicate that populations were nearer to their upper thermal limits, and may therefore be more vulnerable to additional warming.

mean_wt = full_data %>% 
  group_by(site, season) %>% 
  summarize(mean_wt = mean(warming_tol),
            median_wt = median(warming_tol))

ggplot(full_data, aes(x = season, y = warming_tol, colour = site)) + 
  geom_line(data = mean_wt, 
            aes(y = median_wt, group = site),
            position = position_dodge(width = 0.4),
            linewidth = 1) + 
  geom_point(position = position_jitterdodge(jitter.width = 0.1, jitter.height = 0,
                                             dodge.width = 0.4),
             alpha = 0.3) + 
  geom_point(data = mean_wt, 
             aes(y = median_wt),
             position = position_dodge(width = 0.4),
             size = 4) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "Warming Tolerance (°C)",
       x = "Season") +
  theme_matt() + 
  theme(legend.position = "right", 
        legend.title.align = 0.125)

Body Size

Following the CTmax assay, individuals were photographed for body size measurements. Prosome lengths were measured from these photographs using a scale micrometer and the software ImageJ. These measurements are shown below.

mean_size = full_data %>% 
  group_by(site, season) %>% 
  summarize(mean_size = mean(size),
            median_size = median(size))

ggplot(full_data, aes(x = season, y = size, colour = site)) + 
  geom_line(data = mean_size, 
            aes(y = median_size, group = site),
            position = position_dodge(width = 0.4),
            linewidth = 1) + 
  geom_point(position = position_jitterdodge(jitter.width = 0.1, jitter.height = 0,
                                             dodge.width = 0.4),
             alpha = 0.3) + 
  geom_point(data = mean_size, 
             aes(y = median_size),
             position = position_dodge(width = 0.4),
             size = 4) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "Prosome Length (mm)",
       x = "Season") +
  theme_matt() + 
  theme(legend.position = "right", 
        legend.title.align = 0.125)

Salinity Pair Comparisons

sal_comp_ctmax_plot = sal_comps %>% 
  ggplot(aes(x = salinity, y = ctmax, colour = season, group = season)) + 
  facet_wrap(region~.) + 
  geom_point(size = 2,
             position = position_dodge(width = 0.2)) + 
  #geom_line(size = 1.5) + 
  scale_colour_manual(values = season_cols) + 
  labs(y = "CTmax (°C)",
       x = "") + 
  theme_matt_facets(base_size = 14)

sal_comp_size_plot = sal_comps %>% 
  ggplot(aes(x = salinity, y = size, colour = season, group = season)) + 
  facet_wrap(region~.) + 
  geom_point(size = 2, 
             position = position_dodge(width = 0.2)) + 
  #geom_line(size = 1.5) + 
  scale_colour_manual(values = season_cols) + 
  labs(y = "Prosome Length (mm)",
       x = "") + 
  theme_matt_facets(base_size = 14)

ggarrange(sal_comp_ctmax_plot, sal_comp_size_plot, nrow = 2, common.legend = T, legend = "right")


###

sal_comp_ctmax.model = lm(ctmax ~ collection_temp, data = sal_comps)
# summary(ctmax_temp.model)
# car::Anova(ctmax_temp.model)
sal_comp_ctmax_resids = residuals(sal_comp_ctmax.model)

sal_comp_size.model = lm(size ~ collection_temp, data = sal_comps)
# summary(size_temp.model)
# car::Anova(size_temp.model)
sal_comp_size_resids = residuals(sal_comp_size.model)

sal_comp_ctmax_resid_plot = sal_comps %>%
  mutate(ctmax_resids = sal_comp_ctmax_resids,
         size_resids = sal_comp_size_resids) %>%
  ggplot(aes(x = salinity, y = ctmax_resids, colour = season, group = season)) +
  facet_wrap(region~.) +
  geom_point(size = 2,
             position = position_dodge(width = 0.5)) +
  #geom_line(size = 1.5) +
  scale_colour_manual(values = season_cols) +
  labs(y = "CTmax \nResiduals",
       x = "") +
  theme_matt_facets(base_size = 14)

sal_comp_size_resid_plot = sal_comps %>%
  mutate(ctmax_resids = sal_comp_ctmax_resids,
         size_resids = sal_comp_size_resids) %>%
  ggplot(aes(x = salinity, y = size_resids, colour = season, group = season)) +
  facet_wrap(region~.) +
  geom_point(size = 2,
             position = position_dodge(width = 0.5)) +
  #geom_line(size = 1.5) +
  scale_colour_manual(values = season_cols) +
  labs(y = "Prosome Length \nResiduals",
       x = "") +
  theme_matt_facets(base_size = 14)

#ggarrange(sal_comp_ctmax_resid_plot, sal_comp_size_resid_plot, nrow = 2, common.legend = T, legend = "right")

Trait Correlations

We expect that collections from warmer waters should yield copepods with higher thermal limits and smaller body sizes.

ctmax_temp_plot = ggplot(full_data, aes(x = collection_temp, y = ctmax)) + 
  geom_smooth(method = "lm", se = T,
              linewidth = 2, 
              colour = "grey") + 
  geom_point(aes(colour = site), 
             size = 2, alpha = 0.7) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax (°C)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "right")

size_temp_plot = ggplot(full_data, aes(x = collection_temp, y = size)) + 
  geom_smooth(method = "lm", se = T,
              linewidth = 2, 
              colour = "grey") + 
  geom_point(aes(colour = site), 
             size = 2, alpha = 0.7) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "Prosome Length (mm)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "right")

wt_temp_plot = ggplot(full_data, aes(x = collection_temp, y = warming_tol)) + 
  geom_smooth(method = "lm", se = T,
              linewidth = 2, 
              colour = "grey") + 
  geom_point(aes(colour = site), 
             size = 2, alpha = 0.7) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "Warming Tolerance (°C)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "right")

ggarrange(ctmax_temp_plot, wt_temp_plot, size_temp_plot, common.legend = T, legend = "bottom", nrow = 1)

Of particular interest is the relationship between prosome length and CTmax. In many cases, larger body sizes are associated with cold adaptation/acclimation. We may therefore see this pattern emerge across populations or seasons. If populations contain a mix of cold- and warm-adapted genotypes, however, we might also see this relationship emerge within individual collections. Shown below is the relationship between prosome length and CTmax for the individuals measured thus far. Individual regression lines for each site are also included. Note that raw CTmax and body size values are shown, rather than metrics like residuals from a statistical model correcting for variation in collection temperature.

universal_size = full_data %>% 
  ggplot(aes(x = size, y = ctmax)) + 
  # geom_smooth(data = filter(full_data, ctmax > 31), 
  #             aes(x = size, y = ctmax),
  #             method = "lm", 
  #             colour = "grey60", 
  #             se = F,
  #             linewidth = 2) + 
  geom_smooth(method = "lm", se = T,
              linewidth = 2,
              colour = "grey70") + 
  geom_point(aes(colour = site),
             size = 2, alpha = 0.7) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax (°C)",
       x = "") +
  theme_matt(base_size = 14) + 
  theme(legend.position = "right",
        axis.title.x = element_blank())

pop_size = full_data %>% 
  ggplot(aes(x = size, y = ctmax, colour = site, group = season)) + 
  facet_wrap(site~.) + 
  # geom_smooth(data = filter(full_data, ctmax > 31), 
  #             aes(x = size, y = ctmax),
  #             method = "lm", 
  #             colour = "grey60", 
  #             se = F,
  #             linewidth = 2) + 
  geom_point(size = 1.3, alpha = 0.3) + 
  geom_smooth(method = "lm", se = F,
              linewidth = 1) + 
  scale_colour_manual(values = site_cols) + 
  scale_x_continuous(breaks = c(0.6, 0.8, 1)) + 
  labs(y = "CTmax (°C)",
       x = "Prosome Length (mm)") +
  theme_matt(base_size = 14) + 
  theme(legend.position = "right")

ggarrange(universal_size, pop_size, common.legend = T, legend = "none", nrow = 2)

Trait Variability

Shown below is the trait variation (ranges) for each site. Ranges are calculated for each season separately.

trait_ranges = full_data %>% 
  group_by(site, season, collection_temp, collection_salinity, doy, lat) %>% 
  summarise(mean_ctmax = mean(ctmax),
            ctmax_range = max(ctmax) - min(ctmax),
            ctmax_var = var(ctmax),
            mean_size = mean(size),
            size_range = max(size) - min(size),
            size_var = var(size)) %>% 
  mutate(prop_ctmax_range = ctmax_range / mean_ctmax,
         prop_size_range = size_range / mean_size)

ctmax_range_temp = ggplot(trait_ranges, aes(x = collection_temp, y = ctmax_range, colour = site)) + 
  geom_point(size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax Range (°C)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "right")

ctmax_var_temp = ggplot(trait_ranges, aes(x = collection_temp, y = ctmax_var, colour = site)) + 
  geom_point(size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax Range (°C)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "right")

size_range_temp = ggplot(trait_ranges, aes(x = collection_temp, y = size_range, colour = site)) + 
  geom_point(size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "Size Range (mm)",
       x = "Collection Temp. (°C)") +
  theme_matt() + 
  theme(legend.position = "right")

ggarrange(ctmax_range_temp, size_range_temp, common.legend = T, legend = "bottom")

Changes in trait variance may be indicative of phenotypic selection. If selection (as opposed to acclimation) are driving seasonal changes, we may expect to see a reduction in variance in the peak samples relative to the early season samples. Note that early season collection temperatures this year were higher than expected, driven by fairly strong heatwaves in the North Atlantic.

ggplot(trait_ranges, aes(x = season, y = ctmax_var, colour = site)) + 
  geom_line(aes(group = site), 
            linewidth = 1.5) + 
  geom_point(size = 3) + 
  scale_colour_manual(values = site_cols) + 
  labs(y = "CTmax Variance",
       x = "Season") +
  theme_matt() + 
  theme(legend.position = "right", 
        legend.title.align = 0.125)

Next Steps

After phenotyping, each individual was preserved in 95% ethanol. Individual DNA libraries will be prepared using Twist Bio 96-plex prep kits, then sequenced on an Illumina NovaSeq X Plus. Using the low-coverage whole genome sequences, we will examine seasonal patterns in allele frequency change, and compare these fine scale temporal patterns with the larger latitudinal patterns in allele frequency to determine whether the same alleles driving rapid seasonal adaptation are in play over larger spatial (and longer temporal) scales.

Misc. Details

ggplot(temp_record, aes(x = minute_passed, y = temp_C, group = factor(run))) + 
  geom_abline(slope = 0.3, intercept = mean(temp_record[temp_record$minute_interval == 0, 8])) + 
  geom_abline(slope = 0.1, intercept = mean(temp_record[temp_record$minute_interval == 0, 8])) + 
  geom_line(linewidth = 0.2, alpha = 0.8) + 
  geom_point(data = full_data, 
             aes(x = time, y = ctmax + 0.4),
             size = 2,
             shape = 25) +
  labs(x = "Time passed (minutes)",
       y = "Temperature (degrees C)",
       fill = "Trial Number") + 
  guides(colour = "none") + 
  theme_matt(base_size = 16) + 
  theme(legend.position = "right")

ramp_record2 = ramp_record %>% 
  group_by(run, minute_interval) %>% 
  summarise(mean_ramp = mean(ramp_per_minute)) %>% 
  ungroup()

ggplot(ramp_record2, aes(x = minute_interval, y = mean_ramp)) + 
  geom_hline(yintercept = 0.3) + 
  geom_hline(yintercept = 0.1) + 
  #geom_point() + 
  geom_hex(bins = 30) + 
  ylim(0, 0.35) + 
  labs(y = "Ramp Rate (deg. C / min.)",
       x = "Time into run (minute)") + 
  theme_matt(base_size = 16) 

LS0tCnRpdGxlOiAiQ29tcGFyaW5nIHNlYXNvbmFsIGFuZCBsYXRpdHVkaW5hbCBwYXR0ZXJucyBpbiB0aGVybWFsIGFkYXB0YXRpb24iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgICAgICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICAgICAgICB0b2M6IHRydWUKICAgICAgICAgIHRvY19mbG9hdDogdHJ1ZQogIGdpdGh1Yl9kb2N1bWVudDoKICAgICAgICAgIGh0bWxfcHJldmlldzogZmFsc2UKICAgICAgICAgIHRvYzogdHJ1ZQogICAgICAgICAgdG9jX2RlcHRoOiAzCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9VCwgbWVzc2FnZSA9IEYsIHdhcm5pbmcgPSBGLCBlY2hvID0gRn0KCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlY2hvID0ga25pdHI6OmlzX2h0bWxfb3V0cHV0KCksCiAgZmlnLmFsaWduID0gImNlbnRlciIsCiAgZmlnLnBhdGggPSAiLi4vRmlndXJlcy9tYXJrZG93bi8iLAogIGRldiA9IGMoInBuZyIsICJwZGYiKSwKICBtZXNzYWdlID0gRkFMU0UsCiAgd2FybmluZyA9IEZBTFNFLAogIGNvbGxhcHNlID0gVAopCgp0aGVtZV9tYXR0ID0gZnVuY3Rpb24oYmFzZV9zaXplID0gMTgsCiAgICAgICAgICAgICAgICAgICAgICBkYXJrX3RleHQgPSAiZ3JleTIwIil7CiAgbWlkX3RleHQgPC0gIG1vbm9jaHJvbWVSOjpnZW5lcmF0ZV9wYWxldHRlKGRhcmtfdGV4dCwgImdvX2xpZ2h0ZXIiLCBuX2NvbG91cnMgPSA1KVsyXQogIGxpZ2h0X3RleHQgPC0gIG1vbm9jaHJvbWVSOjpnZW5lcmF0ZV9wYWxldHRlKGRhcmtfdGV4dCwgImdvX2xpZ2h0ZXIiLCBuX2NvbG91cnMgPSA1KVszXQogIAogIHRoZW1lX3B1YnIoYmFzZV9mYW1pbHk9InNhbnMiKSAlK3JlcGxhY2UlIAogICAgdGhlbWUoCiAgICAgIHBhbmVsLmJhY2tncm91bmQgID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwgCiAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksCiAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9IG1pZF90ZXh0LCBsaW5laGVpZ2h0ID0gMS4xKSwKICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gZGFya190ZXh0KSwKICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBtaWRfdGV4dCksCiAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDMsIDAsIDAsIDApLCAibW0iKSksCiAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDAsIDUsIDAsIDApLCAibW0iKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmdsZSA9IDkwKSwKICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT1iYXNlX3NpemUgKiAwLjkpLAogICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDAuOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlID0gImJvbGQiKSwKICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMC4yNSwgMC4yNSwgMC4yNSwgMC4yNSwiY20iKQogICAgKQp9Cgp0aGVtZV9tYXR0X2ZhY2V0cyA9IGZ1bmN0aW9uKGJhc2Vfc2l6ZSA9IDE4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhcmtfdGV4dCA9ICJncmV5MjAiKXsKICBtaWRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzJdCiAgbGlnaHRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzNdCiAgCiAgdGhlbWVfYncoYmFzZV9mYW1pbHk9InNhbnMiKSAlK3JlcGxhY2UlIAogICAgdGhlbWUoCiAgICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgIHBhbmVsLmJhY2tncm91bmQgID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwgCiAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksCiAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9IG1pZF90ZXh0LCBsaW5laGVpZ2h0ID0gMS4xKSwKICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUpLAogICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS41LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBkYXJrX3RleHQpLAogICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IG1pZF90ZXh0KSwKICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSB1bml0KGMoMywgMCwgMCwgMCksICJtbSIpKSwKICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSB1bml0KGMoMCwgNSwgMCwgMCksICJtbSIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZ2xlID0gOTApLAogICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPWJhc2Vfc2l6ZSAqIDAuOSksCiAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMC45LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2UgPSAiYm9sZCIpLAogICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbigwLjI1LCAwLjI1LCAwLjI1LCAwLjI1LCJjbSIpCiAgICApCn0KCnNpdGVfY29scyA9IGMoIktleSBMYXJnbyIgPSAiaW5kaWFucmVkNCIsIAogICAgICAgICAgICAgICJNYW5hdGVlIFJpdmVyIiA9ICJjb3JhbCIsIAogICAgICAgICAgICAgICJGdC4gSGFtZXIiID0gImNvcmFsMyIsCiAgICAgICAgICAgICAgIlR5bGVyIENvdmUiID0gImdvbGRlbnJvZDEiLAogICAgICAgICAgICAgICJHYW5leSdzIFdoYXJmIiA9ICJkYXJrZ29sZGVucm9kMyIsIAogICAgICAgICAgICAgICJFc2tlciBQb2ludCIgPSAiZGFya3NlYWdyZWVuMyIsCiAgICAgICAgICAgICAgIlNhd3llciBQYXJrIiA9ICJwYWxlZ3JlZW40IiwgCiAgICAgICAgICAgICAgIlN0LiBUaG9tYXMgZGUgS2VudCBXaGFyZiIgPSAic3RlZWxibHVlMiIsCiAgICAgICAgICAgICAgIlJpdGNoaWUgV2hhcmYiID0gInN0ZWVsYmx1ZTQiKQpgYGAKCiMjIFNpdGUgQ2hhcmFjdGVyaXN0aWNzCgpDb3BlcG9kcyB3ZXJlIGNvbGxlY3RlZCBieSBzdXJmYWNlIHRvdyBmcm9tIHNpdGVzIGFjcm9zcyB0aGUgV2VzdGVybiBBdGxhbnRpYyBhdCBzZXZlcmFsIHRpbWVzIHRocm91Z2hvdXQgdGhlIHllYXIuIFRoZSBzaXRlcyBhcmUgc2hvd24gYmVsb3cuIFRlbXBlcmF0dXJlcyBhdCB0aGUgdGltZSBvZiBjb2xsZWN0aW9uIHdlcmUgbWVhc3VyZWQgdXNpbmcgYSBtYW51YWwgdGhlcm1vbWV0ZXIuCgpgYGB7ciBzaXRlLWNoYXJzLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Nn0KY29vcmRzID0gc2l0ZV9kYXRhICU+JQogIHNlbGVjdChzaXRlLCBsb25nLCBsYXQpICU+JQogIGRpc3RpbmN0KCkKCnNpdGVfbWFwID0gbWFwX2RhdGEoIndvcmxkIikgJT4lIAogIGZpbHRlcihyZWdpb24gJWluJSBjKCJVU0EiLCAiQ2FuYWRhIikpICU+JSAKICBnZ3Bsb3QoKSArIAogIGdlb21fcG9seWdvbihhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApLAogICAgICAgICAgICAgICBmaWxsID0gImxpZ2h0Z3JleSIpICsgCiAgY29vcmRfbWFwKHhsaW0gPSBjKC04NSwtNjApLAogICAgICAgICAgICB5bGltID0gYygyNSwgNDgpKSArIAogIGdlb21fcG9pbnQoZGF0YSA9IGNvb3JkcywKICAgICAgICAgICAgIG1hcHBpbmcgPSBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGNvbG91ciA9IHNpdGUpLAogICAgICAgICAgICAgc2l6ZSA9IDMpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHggPSAiTG9uZ2l0dWRlIiwgCiAgICAgICB5ID0gIkxhdGl0dWRlIikgKyAKICB0aGVtZV9tYXR0KGJhc2Vfc2l6ZSA9IDE2KQoKc2l0ZV90ZW1wX3Bsb3QgPSBmdWxsX2RhdGEgJT4lIAogIHNlbGVjdChzaXRlLCBzZWFzb24sIGRveSwgY29sbGVjdGlvbl90ZW1wLCBjb2xsZWN0aW9uX3NhbGluaXR5KSAlPiUgIAogIGRpc3RpbmN0KCkgJT4lIAogIGZpbHRlcihkb3kgPiAxMDApICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBkb3ksIHkgPSBjb2xsZWN0aW9uX3RlbXAsIGNvbG91ciA9IHNpdGUpKSArIAogIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDYpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAogICAgICAgeCA9ICJEYXkgb2YgdGhlIFllYXIiKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCmdnYXJyYW5nZShzaXRlX21hcCwgc2l0ZV90ZW1wX3Bsb3QsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAiYm90dG9tIikKYGBgCgpFeGFjdCBsb2NhdGlvbnMgZm9yIHRoZSBzaXRlcyBhcmUgcHJvdmlkZWQgaGVyZS4gCgpgYGB7ciBzaXRlLXRhYmxlfQpzaXRlX2RhdGEgJT4lICAKICBhcnJhbmdlKGxhdCkgJT4lICAKICBzZWxlY3QoIlNpdGUiID0gc2l0ZSwgIlJlZ2lvbiIgPSByZWdpb24sICJMYXQiID0gbGF0LCAiTG9uZyIgPSBsb25nKSAlPiUgCiAga25pdHI6OmthYmxlKGFsaWduID0gImMiKQpgYGAKCk5lc3RlZCB3aXRoaW4gZWFjaCBvZiB0aGUgdGhyZWUgcmVnaW9ucyAoU291dGgsIENlbnRyYWwsIGFuZCBOb3J0aGVybiByZWdpb25zKSBhcmUgcGFpcnMgb2YgbG93IGFuZCBoaWdoIHNhbGluaXR5IHNpdGVzOiAgICAKCmBgYHtyIHNhbC10YWJsZX0KZGF0YS5mcmFtZSgiUmVnaW9uIiA9IGMoIlNvdXRoIiwgIkNlbnRyYWwiLCAiTm9ydGgiKSwKICAgICAgICAgICAiTG93IFNhbGluaXR5IiA9IGMoIkZ0LiBIYW1lciIsICJHYW5leSdzIFdoYXJmIiwgIlJpdGNoaWUgV2hhcmYiKSwKICAgICAgICAgICAiSGlnaCBTYWxpbml0eSIgPSBjKCJNYW5hdGVlIFJpdmVyIiwgIlR5bGVyIENvdmUiLCAiU3QuIFRob21hcyBkZSBLZW50IFdoYXJmIikpICU+JSAKICBrbml0cjo6a2FibGUoYWxpZ24gPSAiYyIpCmBgYAoKXCAKClRoZXJlIGFyZSBmYWlybHkgd2VsbC1lc3RhYmxpc2hlZCBkaXZlcmdlbmNlcyBiZXR3ZWVuIGhpZ2ggc2FsaW5pdHkgYW5kIGxvdyBzYWxpbml0eSBwb3B1bGF0aW9ucyBvZiAqQWNhcnRpYSB0b25zYSouIFRoZXNlIHNldHMgb2YgZ2VvZ3JhcGhpY2FsbHkgcHJveGltYXRlIGJ1dCBpc29sYXRlZCBwb3B1bGF0aW9ucyBwcm92aWRlIGluZGVwZW5kZW50IGNvbXBhcmlzb25zIG9mIHRoZSBlZmZlY3RzIG9mIHNlYXNvbmFsaXR5LgoKYGBge3Igc2Vhc29uLXNhbC1jb21wcywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9OH0Kc2Vhc29uX2NvbHMgPSBjKCJlYXJseSIgPSAiZ3JleTc1IiwgCiAgICAgICAgICAgICAgICAicGVhayIgPSAiZ3JleTUwIiwgCiAgICAgICAgICAgICAgICAibGF0ZSIgPSAiZ3JleTI1IikKCnNhbF9yZWdpb25zID0gZGF0YS5mcmFtZShyZWdpb24gPSByZXAoYygiU291dGgiLCAiQ2VudHJhbCIsICJOb3J0aCIpLCBlYWNoID0gMiksIAogICAgICAgICAgICAgICAgICAgICAgICAgc2l0ZSA9IGMoIkZ0LiBIYW1lciIsICJNYW5hdGVlIFJpdmVyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2FuZXkncyBXaGFyZiIsICJUeWxlciBDb3ZlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUml0Y2hpZSBXaGFyZiIsICJTdC4gVGhvbWFzIGRlIEtlbnQgV2hhcmYiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNhbGluaXR5ID0gYygibG93IiwgImhpZ2giKSkKCnNhbF9jb21wcyA9IGZ1bGxfZGF0YSAlPiUgCiAgZmlsdGVyKHNpdGUgJWluJSBzYWxfcmVnaW9ucyRzaXRlKSAlPiUgCiAgaW5uZXJfam9pbihzYWxfcmVnaW9ucywgYnkgPSBjKCJzaXRlIikpICU+JSAKICBzZWxlY3QoIHJlZ2lvbiA9IHJlZ2lvbi55LCBzaXRlLCBzYWxpbml0eSwgc2Vhc29uLCBkb3ksIGNvbGxlY3Rpb25fdGVtcCwgY29sbGVjdGlvbl9zYWxpbml0eSwKICAgICAgICAgIHNpemUsIGN0bWF4LCB3YXJtaW5nX3RvbCkgJT4lIAogIG11dGF0ZShzYWxpbml0eSA9IGZjdF9yZWxldmVsKHNhbGluaXR5LCAibG93IiwgImhpZ2giKSwKICAgICAgICAgcmVnaW9uID0gZmN0X3JlbGV2ZWwocmVnaW9uLCAiU291dGgiLCAiQ2VudHJhbCIsICJOb3J0aCIpKQoKc2FsX2NvbXBfdGVtcHMgPSBzYWxfY29tcHMgJT4lICAKICBzZWxlY3Qoc2FsaW5pdHksIHNlYXNvbiwgcmVnaW9uLCBjb2xsZWN0aW9uX3RlbXAsIGNvbGxlY3Rpb25fc2FsaW5pdHkpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzYWxpbml0eSwgeSA9IGNvbGxlY3Rpb25fdGVtcCwgY29sb3VyID0gc2Vhc29uLCBncm91cCA9IHNlYXNvbikpICsgCiAgZmFjZXRfd3JhcChyZWdpb25+LikgKyAKICBnZW9tX3BvaW50KHNpemUgPSA0KSArIAogIGdlb21fbGluZShsaW5ld2lkdGggPSAxLjUpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzZWFzb25fY29scykgKyAKICBsYWJzKHkgPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIsCiAgICAgICB4ID0gIiIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTQpCgpzYWxfY29tcF9zYWwgPSBzYWxfY29tcHMgJT4lICAKICBzZWxlY3Qoc2FsaW5pdHksIHNlYXNvbiwgcmVnaW9uLCBjb2xsZWN0aW9uX3RlbXAsIGNvbGxlY3Rpb25fc2FsaW5pdHkpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzYWxpbml0eSwgeSA9IGNvbGxlY3Rpb25fc2FsaW5pdHksIGNvbG91ciA9IHNlYXNvbiwgZ3JvdXAgPSBzZWFzb24pKSArIAogIGZhY2V0X3dyYXAocmVnaW9ufi4pICsgCiAgZ2VvbV9wb2ludChzaXplID0gNCkgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMS41KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2Vhc29uX2NvbHMpICsgCiAgbGFicyh5ID0gIkNvbGxlY3Rpb24gU2FsaW5pdHkgKHBzdSkiLAogICAgICAgeCA9ICJTYWxpbml0eSIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTQpCgpnZ2FycmFuZ2Uoc2FsX2NvbXBfdGVtcHMsIHNhbF9jb21wX3NhbCwgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAicmlnaHQiKQoKIyBzYWxfY29tcHMgJT4lICAKIyAgIHNlbGVjdChzaXRlLCBzYWxpbml0eSwgc2Vhc29uLCByZWdpb24sIGNvbGxlY3Rpb25fdGVtcCwgY29sbGVjdGlvbl9zYWxpbml0eSkgJT4lIAojICAgZGlzdGluY3QoKSAlPiUgCiMgICBnZ3Bsb3QoYWVzKHggPSBjb2xsZWN0aW9uX3NhbGluaXR5LCB5ID0gY29sbGVjdGlvbl90ZW1wLCBjb2xvdXIgPSBzaXRlKSkgKyAKIyAgIGZhY2V0X2dyaWQocmVnaW9ufi4pICsgCiMgICBnZW9tX3BvaW50KHNpemUgPSA0KSArIAojICAgI3N0YXRfZWxsaXBzZSgpICsKIyAgICNnZW9tX3BhdGgoYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMSwgImluY2hlcyIpLCB0eXBlID0gImNsb3NlZCIpKSArIAojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiMgICB0aGVtZV9tYXR0X2ZhY2V0cyhiYXNlX3NpemUgPSAxNCkKYGBgCgojIyBDcml0aWNhbCBUaGVybWFsIExpbWl0cwoKQSB0b3RhbCBvZiBgciBkaW0oYWxsX2RhdGEpWzFdYCBpbmRpdmlkdWFscyB3ZXJlIGV4YW1pbmVkLiBDcml0aWNhbCB0aGVybWFsIGxpbWl0cyBhbmQgYm9keSBzaXplIG1lYXN1cmVtZW50cyB3ZXJlIG1hZGUgYmVmb3JlIGluZGl2aWR1YWxzIHdlcmUgcHJlc2VydmVkIGluIGV0aGFub2wuIFdlIGV4Y2x1ZGVkIGRhdGEgZm9yIGByIGRpbShleGNsdWRlZClbMV1gIGluZGl2aWR1YWxzLCBkZXRhaWxlZCBiZWxvdy4gVGhlc2UgaW5kaXZpZHVhbHMgaGFkIGVpdGhlciB2ZXJ5IGxvdyBDVG1heCBvciB3ZXJlLCB1cG9uIHJlLWV4YW1pbmF0aW9uIG9mIHBob3RvZ3JhcGhzLCBpZGVudGlmaWVkIGFzIGp1dmVuaWxlcyBpbnN0ZWFkIG9mIG1hdHVyZSBmZW1hbGVzLiAgCgpgYGB7ciBleGNsdWRlZC1pbmRzfQpleGNsdWRlZCAlPiUgCiAgc2VsZWN0KHJlZ2lvbiwgc2l0ZSwgc2Vhc29uLCBjb2xsZWN0aW9uX3RlbXAsIGNvbGxlY3Rpb25fc2FsaW5pdHksIHJlcGxpY2F0ZSwgdHViZSwgY3RtYXgsIHNpemUpICU+JSAKICBrbml0cjo6a2FibGUoYWxpZ24gPSAiYyIpCmBgYAoKQ3JpdGljYWwgdGhlcm1hbCBtYXhpbWEgKENUbWF4KSB3YXMgbWVhc3VyZWQgdXNpbmcgYSBjdXN0b20gc2V0dXAuIFRoZSBtZXRob2QgdXNlcyBhIHN0YW5kYXJkIGR5bmFtaWMgcmFtcGluZyBhc3NheSB0byBkZXRlcm1pbmUgdGhlIG1heGltdW0gdGVtcGVyYXR1cmUgaW5kaXZpZHVhbHMgY291bGQgc3VzdGFpbiBub3JtYWwgZnVuY3Rpb25pbmcuIFRoaXMgZGlmZmVycyBmcm9tIGxldGhhbCB0ZW1wZXJhdHVyZXMsIGFuZCBpbmRlZWQsIGFsbCBpbmRpdmlkdWFscyBvYnNlcnZlZCBzbyBmYXIgcmVjb3ZlcmVkIGZvbGxvd2luZyB0aGUgYXNzYXkuCgpJbmRpdmlkdWFscyB3ZXJlIHJlc3RlZCBmb3Igb25lIGhvdXIgYWZ0ZXIgY29sbGVjdGlvbiBiZWZvcmUgdGhlIGFzc2F5LiBEdXJpbmcgdGhlIGFzc2F5LCBjb3BlcG9kcyB3ZXJlIGhlbGQgaW4gMC4yIHVtIGZpbHRlcmVkIHNlYXdhdGVyLCBhZGp1c3RlZCB0byBtYXRjaCB0aGUgc2FsaW5pdHkgYXQgdGhlIHRpbWUgb2YgY29sbGVjdGlvbiB3aXRoIGJvdHRsZWQgc3ByaW5nIHdhdGVyLiBEdXJpbmcgdGhlIGFzc2F5LCBzZXZlcmFsICdjb250cm9sJyBpbmRpdmlkdWFscyB3ZXJlIG1haW50YWluZWQgaW4gdGhpcyBhZGp1c3RlZCBzYWxpbml0eSBzb2x1dGlvbiwgYnV0IGRpZCBub3QgZXhwZXJpZW5jZSB0aGUgdGVtcGVyYXR1cmUgcmFtcCwgdG8gZW5zdXJlIHRoYXQgdGhlcmUgd2FzIG5vIGJhY2tncm91bmQgbW9ydGFsaXR5LgoKU2hvd24gYmVsb3cgYXJlIHRoZSBtZWFzdXJlZCBDVG1heCB2YWx1ZXMuIE5vdGU6IENUbWF4IHZhbHVlcyBmb3IgdGhlIGVhcmx5IHNlYXNvbiBLZXkgTGFyZ28gY29wZXBvZHMgd2VyZSBjb2xsZWN0ZWQgYXQgdGhlIGVuZCBvZiBGZWJydWFyeSAyMDIzIGFzIHBhcnQgb2YgYSBzZXBhcmF0ZSBwcm9qZWN0LiBCb2R5IHNpemUgdmFsdWVzIHdlcmUgbm90IG1lYXN1cmVkIGR1cmluZyB0aGlzIHByb2plY3QsIG5vciB3ZXJlIGNvcGVwb2RzIGluZGl2aWR1YWxseSBwcmVzZXJ2ZWQgYWZ0ZXIgdGhlIGV4cGVyaW1lbnRzLiBUaGVzZSBlYXJseSBzZWFzb24gQ1RtYXggdmFsdWVzIGFyZSBpbmNsdWRlZCBhcyBhIHBvaW50IG9mIGNvbXBhcmlzb24uIEluZGl2aWR1YWwgbWVhc3VyZW1lbnRzIGFyZSBzaG93biBpbiBzbWFsbCBwb2ludHMgZm9yIGVhY2ggY29sbGVjdGlvbi4gVGhlIGxhcmdlIHBvaW50IGluZGljYXRlcyB0aGUgbWVkaWFuIHZhbHVlLiAKCmBgYHtyIHNlYXNvbmFsLWN0LW1heH0KbWVhbl9jdG1heCA9IGZ1bGxfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSwgc2Vhc29uKSAlPiUgCiAgc3VtbWFyaXplKG1lYW5fY3RtYXggPSBtZWFuKGN0bWF4KSwKICAgICAgICAgICAgbWVkaWFuX2N0bWF4ID0gbWVkaWFuKGN0bWF4KSkKCmdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gc2Vhc29uLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNpdGUpKSArIAogIGdlb21fbGluZShkYXRhID0gbWVhbl9jdG1heCwgCiAgICAgICAgICAgIGFlcyh5ID0gbWVkaWFuX2N0bWF4LCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyZG9kZ2Uoaml0dGVyLndpZHRoID0gMC4xLCBqaXR0ZXIuaGVpZ2h0ID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9kZ2Uud2lkdGggPSAwLjQpLAogICAgICAgICAgICAgYWxwaGEgPSAwLjMpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gbWVhbl9jdG1heCwgCiAgICAgICAgICAgICBhZXMoeSA9IG1lZGlhbl9jdG1heCksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICB4ID0gIlNlYXNvbiIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgojIyBXYXJtaW5nIHRvbGVyYW5jZQoKV2FybWluZyB0b2xlcmFuY2Ugd2FzIGNhbGN1bGF0ZWQgYXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBtZWFzdXJlZCBDVG1heCB2YWx1ZXMgYW5kIHRoZSBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlLiBMb3dlciB3YXJtaW5nIHRvbGVyYW5jZSB2YWx1ZXMgaW5kaWNhdGUgdGhhdCBwb3B1bGF0aW9ucyB3ZXJlIG5lYXJlciB0byB0aGVpciB1cHBlciB0aGVybWFsIGxpbWl0cywgYW5kIG1heSB0aGVyZWZvcmUgYmUgbW9yZSB2dWxuZXJhYmxlIHRvIGFkZGl0aW9uYWwgd2FybWluZy4gCgpgYGB7ciBzZWFzb25hbC13YXJtaW5nLXRvbH0KbWVhbl93dCA9IGZ1bGxfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSwgc2Vhc29uKSAlPiUgCiAgc3VtbWFyaXplKG1lYW5fd3QgPSBtZWFuKHdhcm1pbmdfdG9sKSwKICAgICAgICAgICAgbWVkaWFuX3d0ID0gbWVkaWFuKHdhcm1pbmdfdG9sKSkKCmdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gc2Vhc29uLCB5ID0gd2FybWluZ190b2wsIGNvbG91ciA9IHNpdGUpKSArIAogIGdlb21fbGluZShkYXRhID0gbWVhbl93dCwgCiAgICAgICAgICAgIGFlcyh5ID0gbWVkaWFuX3d0LCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyZG9kZ2Uoaml0dGVyLndpZHRoID0gMC4xLCBqaXR0ZXIuaGVpZ2h0ID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9kZ2Uud2lkdGggPSAwLjQpLAogICAgICAgICAgICAgYWxwaGEgPSAwLjMpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gbWVhbl93dCwgCiAgICAgICAgICAgICBhZXMoeSA9IG1lZGlhbl93dCksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJXYXJtaW5nIFRvbGVyYW5jZSAowrBDKSIsCiAgICAgICB4ID0gIlNlYXNvbiIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgojIyBCb2R5IFNpemUKCkZvbGxvd2luZyB0aGUgQ1RtYXggYXNzYXksIGluZGl2aWR1YWxzIHdlcmUgcGhvdG9ncmFwaGVkIGZvciBib2R5IHNpemUgbWVhc3VyZW1lbnRzLiBQcm9zb21lIGxlbmd0aHMgd2VyZSBtZWFzdXJlZCBmcm9tIHRoZXNlIHBob3RvZ3JhcGhzIHVzaW5nIGEgc2NhbGUgbWljcm9tZXRlciBhbmQgdGhlIHNvZnR3YXJlIEltYWdlSi4gVGhlc2UgbWVhc3VyZW1lbnRzIGFyZSBzaG93biBiZWxvdy4KCmBgYHtyIHNlYXNvbmFsLWJvZHktc2l6ZX0KbWVhbl9zaXplID0gZnVsbF9kYXRhICU+JSAKICBncm91cF9ieShzaXRlLCBzZWFzb24pICU+JSAKICBzdW1tYXJpemUobWVhbl9zaXplID0gbWVhbihzaXplKSwKICAgICAgICAgICAgbWVkaWFuX3NpemUgPSBtZWRpYW4oc2l6ZSkpCgpnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IHNlYXNvbiwgeSA9IHNpemUsIGNvbG91ciA9IHNpdGUpKSArIAogIGdlb21fbGluZShkYXRhID0gbWVhbl9zaXplLCAKICAgICAgICAgICAgYWVzKHkgPSBtZWRpYW5fc2l6ZSwgZ3JvdXAgPSBzaXRlKSwKICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNCksCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEpICsgCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcmRvZGdlKGppdHRlci53aWR0aCA9IDAuMSwgaml0dGVyLmhlaWdodCA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvZGdlLndpZHRoID0gMC40KSwKICAgICAgICAgICAgIGFscGhhID0gMC4zKSArIAogIGdlb21fcG9pbnQoZGF0YSA9IG1lYW5fc2l6ZSwgCiAgICAgICAgICAgICBhZXMoeSA9IG1lZGlhbl9zaXplKSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICAgc2l6ZSA9IDQpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlByb3NvbWUgTGVuZ3RoIChtbSkiLAogICAgICAgeCA9ICJTZWFzb24iKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduID0gMC4xMjUpCmBgYAoKIyMjIFNhbGluaXR5IFBhaXIgQ29tcGFyaXNvbnMgCgpgYGB7ciBzYWwtcGFpci10cmFpdHN9CnNhbF9jb21wX2N0bWF4X3Bsb3QgPSBzYWxfY29tcHMgJT4lIAogIGdncGxvdChhZXMoeCA9IHNhbGluaXR5LCB5ID0gY3RtYXgsIGNvbG91ciA9IHNlYXNvbiwgZ3JvdXAgPSBzZWFzb24pKSArIAogIGZhY2V0X3dyYXAocmVnaW9ufi4pICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjIpKSArIAogICNnZW9tX2xpbmUoc2l6ZSA9IDEuNSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNlYXNvbl9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICB4ID0gIiIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTQpCgpzYWxfY29tcF9zaXplX3Bsb3QgPSBzYWxfY29tcHMgJT4lIAogIGdncGxvdChhZXMoeCA9IHNhbGluaXR5LCB5ID0gc2l6ZSwgY29sb3VyID0gc2Vhc29uLCBncm91cCA9IHNlYXNvbikpICsgCiAgZmFjZXRfd3JhcChyZWdpb25+LikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyLCAKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjIpKSArIAogICNnZW9tX2xpbmUoc2l6ZSA9IDEuNSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNlYXNvbl9jb2xzKSArIAogIGxhYnMoeSA9ICJQcm9zb21lIExlbmd0aCAobW0pIiwKICAgICAgIHggPSAiIikgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cyhiYXNlX3NpemUgPSAxNCkKCmdnYXJyYW5nZShzYWxfY29tcF9jdG1heF9wbG90LCBzYWxfY29tcF9zaXplX3Bsb3QsIG5yb3cgPSAyLCBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gInJpZ2h0IikKCiMjIwoKc2FsX2NvbXBfY3RtYXgubW9kZWwgPSBsbShjdG1heCB+IGNvbGxlY3Rpb25fdGVtcCwgZGF0YSA9IHNhbF9jb21wcykKIyBzdW1tYXJ5KGN0bWF4X3RlbXAubW9kZWwpCiMgY2FyOjpBbm92YShjdG1heF90ZW1wLm1vZGVsKQpzYWxfY29tcF9jdG1heF9yZXNpZHMgPSByZXNpZHVhbHMoc2FsX2NvbXBfY3RtYXgubW9kZWwpCgpzYWxfY29tcF9zaXplLm1vZGVsID0gbG0oc2l6ZSB+IGNvbGxlY3Rpb25fdGVtcCwgZGF0YSA9IHNhbF9jb21wcykKIyBzdW1tYXJ5KHNpemVfdGVtcC5tb2RlbCkKIyBjYXI6OkFub3ZhKHNpemVfdGVtcC5tb2RlbCkKc2FsX2NvbXBfc2l6ZV9yZXNpZHMgPSByZXNpZHVhbHMoc2FsX2NvbXBfc2l6ZS5tb2RlbCkKCnNhbF9jb21wX2N0bWF4X3Jlc2lkX3Bsb3QgPSBzYWxfY29tcHMgJT4lCiAgbXV0YXRlKGN0bWF4X3Jlc2lkcyA9IHNhbF9jb21wX2N0bWF4X3Jlc2lkcywKICAgICAgICAgc2l6ZV9yZXNpZHMgPSBzYWxfY29tcF9zaXplX3Jlc2lkcykgJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2FsaW5pdHksIHkgPSBjdG1heF9yZXNpZHMsIGNvbG91ciA9IHNlYXNvbiwgZ3JvdXAgPSBzZWFzb24pKSArCiAgZmFjZXRfd3JhcChyZWdpb25+LikgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDIsCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSkgKwogICNnZW9tX2xpbmUoc2l6ZSA9IDEuNSkgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2Vhc29uX2NvbHMpICsKICBsYWJzKHkgPSAiQ1RtYXggXG5SZXNpZHVhbHMiLAogICAgICAgeCA9ICIiKSArCiAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTQpCgpzYWxfY29tcF9zaXplX3Jlc2lkX3Bsb3QgPSBzYWxfY29tcHMgJT4lCiAgbXV0YXRlKGN0bWF4X3Jlc2lkcyA9IHNhbF9jb21wX2N0bWF4X3Jlc2lkcywKICAgICAgICAgc2l6ZV9yZXNpZHMgPSBzYWxfY29tcF9zaXplX3Jlc2lkcykgJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2FsaW5pdHksIHkgPSBzaXplX3Jlc2lkcywgY29sb3VyID0gc2Vhc29uLCBncm91cCA9IHNlYXNvbikpICsKICBmYWNldF93cmFwKHJlZ2lvbn4uKSArCiAgZ2VvbV9wb2ludChzaXplID0gMiwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjUpKSArCiAgI2dlb21fbGluZShzaXplID0gMS41KSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzZWFzb25fY29scykgKwogIGxhYnMoeSA9ICJQcm9zb21lIExlbmd0aCBcblJlc2lkdWFscyIsCiAgICAgICB4ID0gIiIpICsKICB0aGVtZV9tYXR0X2ZhY2V0cyhiYXNlX3NpemUgPSAxNCkKCiNnZ2FycmFuZ2Uoc2FsX2NvbXBfY3RtYXhfcmVzaWRfcGxvdCwgc2FsX2NvbXBfc2l6ZV9yZXNpZF9wbG90LCBucm93ID0gMiwgY29tbW9uLmxlZ2VuZCA9IFQsIGxlZ2VuZCA9ICJyaWdodCIpCmBgYAoKCiMjIFRyYWl0IENvcnJlbGF0aW9ucwoKV2UgZXhwZWN0IHRoYXQgY29sbGVjdGlvbnMgZnJvbSB3YXJtZXIgd2F0ZXJzIHNob3VsZCB5aWVsZCBjb3BlcG9kcyB3aXRoIGhpZ2hlciB0aGVybWFsIGxpbWl0cyBhbmQgc21hbGxlciBib2R5IHNpemVzLgoKYGBge3IgdGVtcC1jb3JzLCBmaWcud2lkdGg9MTUsIGZpZy5oZWlnaHQ9Nn0KY3RtYXhfdGVtcF9wbG90ID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBjdG1heCkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIsIAogICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwgCiAgICAgICAgICAgICBzaXplID0gMiwgYWxwaGEgPSAwLjcpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKc2l6ZV90ZW1wX3Bsb3QgPSBnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IHNpemUpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gVCwKICAgICAgICAgICAgICBsaW5ld2lkdGggPSAyLCAKICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleSIpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gc2l0ZSksIAogICAgICAgICAgICAgc2l6ZSA9IDIsIGFscGhhID0gMC43KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJQcm9zb21lIExlbmd0aCAobW0pIiwKICAgICAgIHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKd3RfdGVtcF9wbG90ID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSB3YXJtaW5nX3RvbCkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIsIAogICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwgCiAgICAgICAgICAgICBzaXplID0gMiwgYWxwaGEgPSAwLjcpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIldhcm1pbmcgVG9sZXJhbmNlICjCsEMpIiwKICAgICAgIHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKZ2dhcnJhbmdlKGN0bWF4X3RlbXBfcGxvdCwgd3RfdGVtcF9wbG90LCBzaXplX3RlbXBfcGxvdCwgY29tbW9uLmxlZ2VuZCA9IFQsIGxlZ2VuZCA9ICJib3R0b20iLCBucm93ID0gMSkKYGBgCgpPZiBwYXJ0aWN1bGFyIGludGVyZXN0IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBwcm9zb21lIGxlbmd0aCBhbmQgQ1RtYXguIEluIG1hbnkgY2FzZXMsIGxhcmdlciBib2R5IHNpemVzIGFyZSBhc3NvY2lhdGVkIHdpdGggY29sZCBhZGFwdGF0aW9uL2FjY2xpbWF0aW9uLiBXZSBtYXkgdGhlcmVmb3JlIHNlZSB0aGlzIHBhdHRlcm4gZW1lcmdlIGFjcm9zcyBwb3B1bGF0aW9ucyBvciBzZWFzb25zLiBJZiBwb3B1bGF0aW9ucyBjb250YWluIGEgbWl4IG9mIGNvbGQtIGFuZCB3YXJtLWFkYXB0ZWQgZ2Vub3R5cGVzLCBob3dldmVyLCB3ZSBtaWdodCBhbHNvIHNlZSB0aGlzIHJlbGF0aW9uc2hpcCBlbWVyZ2UgKip3aXRoaW4qKiBpbmRpdmlkdWFsIGNvbGxlY3Rpb25zLiBTaG93biBiZWxvdyBpcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gcHJvc29tZSBsZW5ndGggYW5kIENUbWF4IGZvciB0aGUgaW5kaXZpZHVhbHMgbWVhc3VyZWQgdGh1cyBmYXIuIEluZGl2aWR1YWwgcmVncmVzc2lvbiBsaW5lcyBmb3IgZWFjaCBzaXRlIGFyZSBhbHNvIGluY2x1ZGVkLiBOb3RlIHRoYXQgcmF3IENUbWF4IGFuZCBib2R5IHNpemUgdmFsdWVzIGFyZSBzaG93biwgcmF0aGVyIHRoYW4gbWV0cmljcyBsaWtlIHJlc2lkdWFscyBmcm9tIGEgc3RhdGlzdGljYWwgbW9kZWwgY29ycmVjdGluZyBmb3IgdmFyaWF0aW9uIGluIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUuCgpgYGB7ciBjdG1heC12cy1zaXplLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD0xMH0KdW5pdmVyc2FsX3NpemUgPSBmdWxsX2RhdGEgJT4lIAogIGdncGxvdChhZXMoeCA9IHNpemUsIHkgPSBjdG1heCkpICsgCiAgIyBnZW9tX3Ntb290aChkYXRhID0gZmlsdGVyKGZ1bGxfZGF0YSwgY3RtYXggPiAzMSksIAogICMgICAgICAgICAgICAgYWVzKHggPSBzaXplLCB5ID0gY3RtYXgpLAogICMgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgCiAgIyAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTYwIiwgCiAgIyAgICAgICAgICAgICBzZSA9IEYsCiAgIyAgICAgICAgICAgICBsaW5ld2lkdGggPSAyKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gVCwKICAgICAgICAgICAgICBsaW5ld2lkdGggPSAyLAogICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5NzAiKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHNpdGUpLAogICAgICAgICAgICAgc2l6ZSA9IDIsIGFscGhhID0gMC43KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICB4ID0gIiIpICsKICB0aGVtZV9tYXR0KGJhc2Vfc2l6ZSA9IDE0KSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKQoKcG9wX3NpemUgPSBmdWxsX2RhdGEgJT4lIAogIGdncGxvdChhZXMoeCA9IHNpemUsIHkgPSBjdG1heCwgY29sb3VyID0gc2l0ZSwgZ3JvdXAgPSBzZWFzb24pKSArIAogIGZhY2V0X3dyYXAoc2l0ZX4uKSArIAogICMgZ2VvbV9zbW9vdGgoZGF0YSA9IGZpbHRlcihmdWxsX2RhdGEsIGN0bWF4ID4gMzEpLCAKICAjICAgICAgICAgICAgIGFlcyh4ID0gc2l6ZSwgeSA9IGN0bWF4KSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIAogICMgICAgICAgICAgICAgY29sb3VyID0gImdyZXk2MCIsIAogICMgICAgICAgICAgICAgc2UgPSBGLAogICMgICAgICAgICAgICAgbGluZXdpZHRoID0gMikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAxLjMsIGFscGhhID0gMC4zKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwKICAgICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDAuNiwgMC44LCAxKSkgKyAKICBsYWJzKHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgeCA9ICJQcm9zb21lIExlbmd0aCAobW0pIikgKwogIHRoZW1lX21hdHQoYmFzZV9zaXplID0gMTQpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCmdnYXJyYW5nZSh1bml2ZXJzYWxfc2l6ZSwgcG9wX3NpemUsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAibm9uZSIsIG5yb3cgPSAyKQpgYGAKCmBgYHtyIGluY2x1ZGUgPSBGfQpmaWx0ZXJlZF9kYXRhID0gZnVsbF9kYXRhICU+JSAKICBkcm9wX25hKHNpemUsIGN0bWF4KQoKY3RtYXhfdGVtcC5tb2RlbCA9IGxtKGN0bWF4IH4gY29sbGVjdGlvbl90ZW1wICsgc2l0ZSwgZGF0YSA9IGZpbHRlcmVkX2RhdGEpCmN0bWF4X3Jlc2lkcyA9IHJlc2lkdWFscyhjdG1heF90ZW1wLm1vZGVsKQoKc2l6ZV90ZW1wLm1vZGVsID0gbG0oc2l6ZSB+IGNvbGxlY3Rpb25fdGVtcCArIHNpdGUsIGRhdGEgPSBmaWx0ZXJlZF9kYXRhKQpzaXplX3Jlc2lkcyA9IHJlc2lkdWFscyhzaXplX3RlbXAubW9kZWwpCgp1bml2ZXJzYWxfcmVzaWRzID0gZmlsdGVyZWRfZGF0YSAlPiUgCiAgbXV0YXRlKGN0bWF4X3Jlc2lkcyA9IGN0bWF4X3Jlc2lkcywKICAgICAgICAgc2l6ZV9yZXNpZHMgPSBzaXplX3Jlc2lkcykgJT4lIAogIGdncGxvdChhZXMoeCA9IHNpemVfcmVzaWRzLCB5ID0gY3RtYXhfcmVzaWRzKSkgKyAKICAjIGdlb21fc21vb3RoKGRhdGEgPSBmaWx0ZXIoZnVsbF9kYXRhLCBjdG1heCA+IDMxKSwgCiAgIyAgICAgICAgICAgICBhZXMoeCA9IHNpemUsIHkgPSBjdG1heCksCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCAKICAjICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5NjAiLCAKICAjICAgICAgICAgICAgIHNlID0gRiwKICAjICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIsCiAgICAgICAgICAgICAgY29sb3VyID0gImdyZXk3MCIpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gc2l0ZSksCiAgICAgICAgICAgICBzaXplID0gMiwgYWxwaGEgPSAwLjcpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIkNUbWF4IFJlc2lkdWFscyIsCiAgICAgICB4ID0gIiIpICsKICB0aGVtZV9tYXR0KGJhc2Vfc2l6ZSA9IDE0KSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKQoKcG9wX3Jlc2lkcyA9IGZpbHRlcmVkX2RhdGEgJT4lIAogIG11dGF0ZShjdG1heF9yZXNpZHMgPSBjdG1heF9yZXNpZHMsCiAgICAgICAgIHNpemVfcmVzaWRzID0gc2l6ZV9yZXNpZHMpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzaXplX3Jlc2lkcywgeSA9IGN0bWF4X3Jlc2lkcywgY29sb3VyID0gc2l0ZSwgZ3JvdXAgPSBzZWFzb24pKSArIAogIGZhY2V0X3dyYXAoc2l0ZX4uKSArIAogICMgZ2VvbV9zbW9vdGgoZGF0YSA9IGZpbHRlcihmdWxsX2RhdGEsIGN0bWF4ID4gMzEpLCAKICAjICAgICAgICAgICAgIGFlcyh4ID0gc2l6ZSwgeSA9IGN0bWF4KSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIAogICMgICAgICAgICAgICAgY29sb3VyID0gImdyZXk2MCIsIAogICMgICAgICAgICAgICAgc2UgPSBGLAogICMgICAgICAgICAgICAgbGluZXdpZHRoID0gMikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAxLjMsIGFscGhhID0gMC4zKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwKICAgICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCBSZXNpZHVhbHMiLAogICAgICAgeCA9ICJQcm9zb21lIExlbmd0aCBSZXNpZHVhbHMiKSArCiAgdGhlbWVfbWF0dChiYXNlX3NpemUgPSAxNCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKZ2dhcnJhbmdlKHVuaXZlcnNhbF9yZXNpZHMsIHBvcF9yZXNpZHMsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAibm9uZSIsIG5yb3cgPSAyKQpgYGAKCmBgYHtyIGN0bWF4LW1vZGVsLCBpbmNsdWRlID0gRn0KY3RtYXgubW9kZWwgPSBsbWU0OjpsbWVyKGRhdGEgPSBmdWxsX2RhdGEsCiAgICAgICAgICAgY3RtYXggfiBjb2xsZWN0aW9uX3RlbXAgKyBzaXplICsgKDF8c2l0ZSkpCgpzdW1tYXJ5KGN0bWF4Lm1vZGVsKQpjYXI6OkFub3ZhKGN0bWF4Lm1vZGVsKQpgYGAKCgojIyBUcmFpdCBWYXJpYWJpbGl0eQoKU2hvd24gYmVsb3cgaXMgdGhlIHRyYWl0IHZhcmlhdGlvbiAocmFuZ2VzKSBmb3IgZWFjaCBzaXRlLiBSYW5nZXMgYXJlIGNhbGN1bGF0ZWQgZm9yIGVhY2ggc2Vhc29uIHNlcGFyYXRlbHkuCgpgYGB7ciB0cmFpdC1yYW5nZS1wbG90fQp0cmFpdF9yYW5nZXMgPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNpdGUsIHNlYXNvbiwgY29sbGVjdGlvbl90ZW1wLCBjb2xsZWN0aW9uX3NhbGluaXR5LCBkb3ksIGxhdCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2N0bWF4ID0gbWVhbihjdG1heCksCiAgICAgICAgICAgIGN0bWF4X3JhbmdlID0gbWF4KGN0bWF4KSAtIG1pbihjdG1heCksCiAgICAgICAgICAgIGN0bWF4X3ZhciA9IHZhcihjdG1heCksCiAgICAgICAgICAgIG1lYW5fc2l6ZSA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgIHNpemVfcmFuZ2UgPSBtYXgoc2l6ZSkgLSBtaW4oc2l6ZSksCiAgICAgICAgICAgIHNpemVfdmFyID0gdmFyKHNpemUpKSAlPiUgCiAgbXV0YXRlKHByb3BfY3RtYXhfcmFuZ2UgPSBjdG1heF9yYW5nZSAvIG1lYW5fY3RtYXgsCiAgICAgICAgIHByb3Bfc2l6ZV9yYW5nZSA9IHNpemVfcmFuZ2UgLyBtZWFuX3NpemUpCgpjdG1heF9yYW5nZV90ZW1wID0gZ2dwbG90KHRyYWl0X3JhbmdlcywgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBjdG1heF9yYW5nZSwgY29sb3VyID0gc2l0ZSkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiQ1RtYXggUmFuZ2UgKMKwQykiLAogICAgICAgeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpjdG1heF92YXJfdGVtcCA9IGdncGxvdCh0cmFpdF9yYW5nZXMsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXhfdmFyLCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCBSYW5nZSAowrBDKSIsCiAgICAgICB4ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCnNpemVfcmFuZ2VfdGVtcCA9IGdncGxvdCh0cmFpdF9yYW5nZXMsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gc2l6ZV9yYW5nZSwgY29sb3VyID0gc2l0ZSkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiU2l6ZSBSYW5nZSAobW0pIiwKICAgICAgIHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKZ2dhcnJhbmdlKGN0bWF4X3JhbmdlX3RlbXAsIHNpemVfcmFuZ2VfdGVtcCwgY29tbW9uLmxlZ2VuZCA9IFQsIGxlZ2VuZCA9ICJib3R0b20iKQpgYGAKCkNoYW5nZXMgaW4gdHJhaXQgdmFyaWFuY2UgbWF5IGJlIGluZGljYXRpdmUgb2YgcGhlbm90eXBpYyBzZWxlY3Rpb24uIElmIHNlbGVjdGlvbiAoYXMgb3Bwb3NlZCB0byBhY2NsaW1hdGlvbikgYXJlIGRyaXZpbmcgc2Vhc29uYWwgY2hhbmdlcywgd2UgbWF5IGV4cGVjdCB0byBzZWUgYSByZWR1Y3Rpb24gaW4gdmFyaWFuY2UgaW4gdGhlIHBlYWsgc2FtcGxlcyByZWxhdGl2ZSB0byB0aGUgZWFybHkgc2Vhc29uIHNhbXBsZXMuIE5vdGUgdGhhdCBlYXJseSBzZWFzb24gY29sbGVjdGlvbiB0ZW1wZXJhdHVyZXMgdGhpcyB5ZWFyIHdlcmUgaGlnaGVyIHRoYW4gZXhwZWN0ZWQsIGRyaXZlbiBieSBmYWlybHkgc3Ryb25nIGhlYXR3YXZlcyBpbiB0aGUgTm9ydGggQXRsYW50aWMuICAgIAoKYGBge3Igc2Vhc29uLXZhcn0KZ2dwbG90KHRyYWl0X3JhbmdlcywgYWVzKHggPSBzZWFzb24sIHkgPSBjdG1heF92YXIsIGNvbG91ciA9IHNpdGUpKSArIAogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzaXRlKSwgCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEuNSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCBWYXJpYW5jZSIsCiAgICAgICB4ID0gIlNlYXNvbiIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgpgYGB7ciB2YXItY2hhbmdlLXRlbXAtY2hhbmdlLCBpbmNsdWRlID0gRn0KdmFyX2NoYW5nZV9kYXRhID0gdHJhaXRfcmFuZ2VzICU+JSAgCiAgZ3JvdXBfYnkoc2l0ZSkgJT4lIAogIGFycmFuZ2UoZG95KSAlPiUgIAogIG11dGF0ZSh0ZW1wX2NoYW5nZSA9IGNvbGxlY3Rpb25fdGVtcCAtIGxhZyhjb2xsZWN0aW9uX3RlbXApLAogICAgICAgICBjdG1heF9jaGFuZ2UgPSBtZWFuX2N0bWF4IC0gbGFnKG1lYW5fY3RtYXgpLAogICAgICAgICB2YXJfY2hhbmdlID0gY3RtYXhfdmFyIC0gbGFnKGN0bWF4X3ZhcikpICU+JSAgCiAgc2VsZWN0KHNpdGUsIHNlYXNvbiwgZG95LCBsYXQsIHRlbXBfY2hhbmdlLCB2YXJfY2hhbmdlLCBjdG1heF9jaGFuZ2UpCgpnZ3Bsb3QodmFyX2NoYW5nZV9kYXRhLCBhZXMoeCA9IHRlbXBfY2hhbmdlLCB5ID0gdmFyX2NoYW5nZSwgY29sb3VyID0gc2l0ZSkpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHggPSAiVGVtcGVyYXR1cmUgQ2hhbmdlICjCsEMpIiwKICAgICAgIHkgPSAiQ2hhbmdlIGluIENUbWF4IFZhcmlhbmNlIikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgojIyBOZXh0IFN0ZXBzCgpBZnRlciBwaGVub3R5cGluZywgZWFjaCBpbmRpdmlkdWFsIHdhcyBwcmVzZXJ2ZWQgaW4gOTUlIGV0aGFub2wuIEluZGl2aWR1YWwgRE5BIGxpYnJhcmllcyB3aWxsIGJlIHByZXBhcmVkIHVzaW5nIFR3aXN0IEJpbyA5Ni1wbGV4IHByZXAga2l0cywgdGhlbiBzZXF1ZW5jZWQgb24gYW4gSWxsdW1pbmEgTm92YVNlcSBYIFBsdXMuIFVzaW5nIHRoZSBsb3ctY292ZXJhZ2Ugd2hvbGUgZ2Vub21lIHNlcXVlbmNlcywgd2Ugd2lsbCBleGFtaW5lIHNlYXNvbmFsIHBhdHRlcm5zIGluIGFsbGVsZSBmcmVxdWVuY3kgY2hhbmdlLCBhbmQgY29tcGFyZSB0aGVzZSBmaW5lIHNjYWxlIHRlbXBvcmFsIHBhdHRlcm5zIHdpdGggdGhlIGxhcmdlciBsYXRpdHVkaW5hbCBwYXR0ZXJucyBpbiBhbGxlbGUgZnJlcXVlbmN5IHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBzYW1lIGFsbGVsZXMgZHJpdmluZyByYXBpZCBzZWFzb25hbCBhZGFwdGF0aW9uIGFyZSBpbiBwbGF5IG92ZXIgbGFyZ2VyIHNwYXRpYWwgKGFuZCBsb25nZXIgdGVtcG9yYWwpIHNjYWxlcy4KCiMjIE1pc2MuIERldGFpbHMKCmBgYHtyIHRlbXAtcmVjb3JkLXBsb3QsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTZ9CmdncGxvdCh0ZW1wX3JlY29yZCwgYWVzKHggPSBtaW51dGVfcGFzc2VkLCB5ID0gdGVtcF9DLCBncm91cCA9IGZhY3RvcihydW4pKSkgKyAKICBnZW9tX2FibGluZShzbG9wZSA9IDAuMywgaW50ZXJjZXB0ID0gbWVhbih0ZW1wX3JlY29yZFt0ZW1wX3JlY29yZCRtaW51dGVfaW50ZXJ2YWwgPT0gMCwgOF0pKSArIAogIGdlb21fYWJsaW5lKHNsb3BlID0gMC4xLCBpbnRlcmNlcHQgPSBtZWFuKHRlbXBfcmVjb3JkW3RlbXBfcmVjb3JkJG1pbnV0ZV9pbnRlcnZhbCA9PSAwLCA4XSkpICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDAuMiwgYWxwaGEgPSAwLjgpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gZnVsbF9kYXRhLCAKICAgICAgICAgICAgIGFlcyh4ID0gdGltZSwgeSA9IGN0bWF4ICsgMC40KSwKICAgICAgICAgICAgIHNpemUgPSAyLAogICAgICAgICAgICAgc2hhcGUgPSAyNSkgKwogIGxhYnMoeCA9ICJUaW1lIHBhc3NlZCAobWludXRlcykiLAogICAgICAgeSA9ICJUZW1wZXJhdHVyZSAoZGVncmVlcyBDKSIsCiAgICAgICBmaWxsID0gIlRyaWFsIE51bWJlciIpICsgCiAgZ3VpZGVzKGNvbG91ciA9ICJub25lIikgKyAKICB0aGVtZV9tYXR0KGJhc2Vfc2l6ZSA9IDE2KSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKYGBge3IgcmFtcC1yZWNvcmQtcGxvdCwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0KcmFtcF9yZWNvcmQyID0gcmFtcF9yZWNvcmQgJT4lIAogIGdyb3VwX2J5KHJ1biwgbWludXRlX2ludGVydmFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fcmFtcCA9IG1lYW4ocmFtcF9wZXJfbWludXRlKSkgJT4lIAogIHVuZ3JvdXAoKQoKZ2dwbG90KHJhbXBfcmVjb3JkMiwgYWVzKHggPSBtaW51dGVfaW50ZXJ2YWwsIHkgPSBtZWFuX3JhbXApKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMykgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLjEpICsgCiAgI2dlb21fcG9pbnQoKSArIAogIGdlb21faGV4KGJpbnMgPSAzMCkgKyAKICB5bGltKDAsIDAuMzUpICsgCiAgbGFicyh5ID0gIlJhbXAgUmF0ZSAoZGVnLiBDIC8gbWluLikiLAogICAgICAgeCA9ICJUaW1lIGludG8gcnVuIChtaW51dGUpIikgKyAKICB0aGVtZV9tYXR0KGJhc2Vfc2l6ZSA9IDE2KSAKYGBgCg==